package cc.cc4414.cc02.chat.service.impl;

import java.util.Date;
import java.util.List;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cc.cc4414.cc02.chat.entity.Friend;
import cc.cc4414.cc02.chat.repository.FriendRepository;
import cc.cc4414.cc02.chat.service.FriendService;
import cc.cc4414.cc02.core.result.ResultEnum;
import cc.cc4414.cc02.core.result.ResultException;
import cc.cc4414.cc02.system.entity.User;
import cc.cc4414.cc02.system.repository.UserRepository;
import lombok.extern.slf4j.Slf4j;

/**
 * @author cc 2018年9月7日
 */
@Service
@Slf4j
public class FriendServiceImpl implements FriendService {

	@Autowired
	private UserRepository userRepository;

	@Autowired
	private FriendRepository friendRepository;

	@Override
	public void add(Long userId, Long friendId) {
		// 用户不能添加自己为好友
		if (userId.equals(friendId)) {
			throw new ResultException(ResultEnum.CAN_NOT_ADD_YOURSELF);
		}
		// 添加好友的用户不能不存在
		Optional<User> optional = userRepository.findById(friendId);
		if (!optional.isPresent() || !optional.get().getState().equals(0)) {
			log.warn("id为{}的用户不存在", userId);
			throw new ResultException(ResultEnum.USER_NOT_EXIST);
		}
		// 不能添加自己已有的好友
		Friend myFriend = friendRepository.findByUserIdAndFriendId(userId, friendId);
		if (myFriend != null) {
			throw new ResultException(ResultEnum.FRIEND_EXISTED);
		}
		// 自己不能在对方的黑名单中
		Friend friend2 = friendRepository.findByUserIdAndFriendId(friendId, userId);
		if (friend2 != null && friend2.getState().equals(2)) {
			throw new ResultException(ResultEnum.FRIEND_BLACKLIST);
		}
		if (friend2 != null && friend2.getState().equals(0)) {
			// 如果对方已关注自己，直接添加为好友
			friend2.setState(1);
			friendRepository.save(friend2);
			save(userId, friendId, 1);
		} else {
			// 否则添加为关注
			save(userId, friendId, 0);
		}
	}

	/**
	 * 新增friend数据
	 * 
	 * @param userId
	 *            用户id
	 * @param friendId
	 *            好友id
	 * @param state
	 *            状态码：0为关注，1为好友，2为黑名单
	 */
	private void save(Long userId, Long friendId, Integer state) {
		User user = userRepository.findById(userId).get();
		User user2 = userRepository.findById(friendId).get();
		Friend friend = new Friend();
		friend.setCreateTime(new Date());
		friend.setUserId(userId);
		friend.setUserNickname(user.getNickname());
		friend.setFriendId(friendId);
		friend.setFriendNickname(user2.getNickname());
		friend.setState(state);
		friend.setLastMessageSendId(0L);
		friendRepository.save(friend);
	}

	@Override
	public void cancelAdd(Long userId, Long friendId) {
		Friend myFriend = friendRepository.findByUserIdAndFriendId(userId, friendId);
		// 如果不是关注对方的状态，不能取消关注
		if (myFriend == null || !myFriend.getState().equals(0)) {
			throw new ResultException(ResultEnum.NOT_ADD_FRIEND);
		}
		friendRepository.delete(myFriend);
	}

	@Override
	public void accept(Long userId, Long friendId) {
		Friend friend2 = friendRepository.findByUserIdAndFriendId(friendId, userId);
		// 对方未关注自己，则不能同意添加对方为好友
		if (friend2 == null || !friend2.getState().equals(0)) {
			throw new ResultException(ResultEnum.NOT_ADD_FRIEND);
		}
		// 对方对自己的状态改为好友
		friend2.setState(1);
		friendRepository.save(friend2);
		Friend myFriend = friendRepository.findByUserIdAndFriendId(userId, friendId);
		// 自己对对方的状态改为好友
		if (myFriend != null) {
			myFriend.setState(1);
			friendRepository.save(myFriend);
		} else {
			save(userId, friendId, 1);
		}
	}

	@Override
	public void delete(Long userId, Long friendId) {
		Friend myFriend = friendRepository.findByUserIdAndFriendId(userId, friendId);
		// 对方不是自己的好友则删除失败
		if (myFriend == null || !myFriend.getState().equals(1)) {
			throw new ResultException(ResultEnum.NOT_FRIEND);
		}
		friendRepository.delete(myFriend);
		Friend friend2 = friendRepository.findByUserIdAndFriendId(friendId, userId);
		if (friend2 != null) {
			friend2.setState(0);
			friendRepository.save(friend2);
		}
	}

	@Override
	public void addBlacklist(Long userId, Long friendId) {
		Friend myFriend = friendRepository.findByUserIdAndFriendId(userId, friendId);
		if (myFriend != null && myFriend.getState().equals(2)) {
			throw new ResultException(ResultEnum.ALREADY_BLACKLIST);
		}
		if (myFriend != null) {
			myFriend.setState(2);
			friendRepository.save(myFriend);
		} else {
			save(userId, friendId, 2);
		}
	}

	@Override
	public void removeBlacklist(Long userId, Long friendId) {
		Friend myFriend = friendRepository.findByUserIdAndFriendId(userId, friendId);
		if (myFriend == null || !myFriend.getState().equals(2)) {
			throw new ResultException(ResultEnum.NOT_BLACKLIST);
		}
		friendRepository.delete(myFriend);
	}

	@Override
	public List<Friend> findFriends(Long userId) {
		return friendRepository.findByUserId(userId);
	}

	@Override
	public List<Friend> findAddMe(Long userId) {
		return friendRepository.findByFriendIdAndState(userId, 0);
	}

}
